package com.smart.community.region.controller;

import java.math.BigDecimal;
import java.util.List;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.smart.community.commons.annotation.ApiLog;
import com.smart.community.commons.enums.ApiLogOperationType;
import com.smart.community.commons.result.Result;
import com.smart.community.region.dto.ShopOwnerRelationDTO;
import com.smart.community.region.service.IShopOwnerRelationService;
import com.smart.community.region.vo.ShopOwnerRelationVO;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;

/**
 * 店铺业主关联管理控制器
 * 
 * @author Wu.Liang
 * @version 1.0.0
 * @since 2025-01-30
 */
@Slf4j
@RestController
@RequestMapping("/region/shop-owner-relation")
@Tag(name = "店铺业主关联管理", description = "店铺业主关联关系相关接口")
public class ShopOwnerRelationController {
    
    @Autowired
    private IShopOwnerRelationService shopOwnerRelationService;
    
    /**
     * 分页查询店铺业主关联列表
     */
    @GetMapping("/page")
    @Operation(summary = "分页查询店铺业主关联列表", description = "根据条件分页查询店铺业主关联列表")
    public Result<IPage<ShopOwnerRelationVO>> getShopOwnerRelationPage(
            @Parameter(description = "当前页", example = "1") @RequestParam(defaultValue = "1") Integer current,
            @Parameter(description = "每页大小", example = "10") @RequestParam(defaultValue = "10") Integer size,
            @Parameter(description = "店铺ID") @RequestParam(required = false) Long shopId,
            @Parameter(description = "业主ID") @RequestParam(required = false) Long ownerId,
            @Parameter(description = "关系类型") @RequestParam(required = false) Integer relationType,
            @Parameter(description = "状态") @RequestParam(required = false) Integer status) {
        try {
            log.info("分页查询店铺业主关联列表，当前页：{}，每页大小：{}，店铺ID：{}，业主ID：{}，关系类型：{}，状态：{}", 
                    current, size, shopId, ownerId, relationType, status);
            
            // 参数校验
            if (current == null || current < 1) {
                return Result.fail("页码必须大于0");
            }
            if (size == null || size < 1 || size > 100) {
                return Result.fail("每页大小必须在1-100之间");
            }
            
            // 调用Service查询
            IPage<ShopOwnerRelationVO> relationPage = shopOwnerRelationService.getShopOwnerRelationPage(
                new Page<>(current, size), shopId, ownerId, relationType, status);
            
            log.info("分页查询店铺业主关联列表成功，总记录数：{}", relationPage != null ? relationPage.getTotal() : 0);
            return Result.success("查询成功", relationPage);
        } catch (Exception e) {
            log.error("分页查询店铺业主关联列表失败", e);
            return Result.fail("查询失败：" + e.getMessage());
        }
    }
    
    /**
     * 根据ID查询店铺业主关联详情
     */
    @GetMapping("/{id}")
    @Operation(summary = "查询店铺业主关联详情", description = "根据ID查询店铺业主关联详情")
    public Result<ShopOwnerRelationVO> getShopOwnerRelationById(
            @Parameter(description = "关联ID", example = "1") @PathVariable Long id) {
        try {
            log.info("查询店铺业主关联详情，ID：{}", id);
            
            // 参数校验
            if (id == null || id <= 0) {
                return Result.fail("关联ID必须大于0");
            }
            
            // 调用Service查询
            ShopOwnerRelationVO relationVO = shopOwnerRelationService.getShopOwnerRelationById(id);
            if (relationVO == null) {
                return Result.fail("关联关系不存在");
            }
            
            log.info("查询店铺业主关联详情成功，店铺名称：{}，业主姓名：{}", 
                    relationVO.getShopName(), relationVO.getOwnerName());
            return Result.success("查询成功", relationVO);
        } catch (Exception e) {
            log.error("查询店铺业主关联详情失败，ID：{}", id, e);
            return Result.fail("查询失败：" + e.getMessage());
        }
    }
    
    /**
     * 创建店铺业主关联
     */
    @ApiLog(
        logTitle = "创建店铺业主关联",
        logType = 2,
        moduleName = "店铺业主关联管理",
        operationType = ApiLogOperationType.ADD
    )
    @PostMapping
    @Operation(summary = "创建店铺业主关联", description = "创建新的店铺业主关联关系")
    public Result<Long> createShopOwnerRelation(@RequestBody @Valid ShopOwnerRelationDTO relationDTO) {
        try {
            log.info("创建店铺业主关联，店铺ID：{}，业主ID：{}", relationDTO.getShopId(), relationDTO.getOwnerId());
            
            // 业务参数校验
            validateShopOwnerRelationDTO(relationDTO);
            
            // 调用Service创建
            Long relationId = shopOwnerRelationService.createShopOwnerRelation(relationDTO);
            
            log.info("创建店铺业主关联成功，关联ID：{}，店铺ID：{}，业主ID：{}", 
                    relationId, relationDTO.getShopId(), relationDTO.getOwnerId());
            return Result.success("创建成功", relationId);
        } catch (Exception e) {
            log.error("创建店铺业主关联失败，店铺ID：{}，业主ID：{}", 
                    relationDTO != null ? relationDTO.getShopId() : "未知", 
                    relationDTO != null ? relationDTO.getOwnerId() : "未知", e);
            return Result.fail("创建失败：" + e.getMessage());
        }
    }
    
    /**
     * 更新店铺业主关联
     */
    @ApiLog(
        logTitle = "更新店铺业主关联",
        logType = 2,
        moduleName = "店铺业主关联管理",
        operationType = ApiLogOperationType.UPDATE
    )
    @PutMapping("/{id}")
    @Operation(summary = "更新店铺业主关联", description = "更新店铺业主关联关系")
    public Result<Boolean> updateShopOwnerRelation(
            @Parameter(description = "关联ID", example = "1") @PathVariable Long id,
            @RequestBody @Valid ShopOwnerRelationDTO relationDTO) {
        try {
            log.info("更新店铺业主关联，ID：{}，店铺ID：{}，业主ID：{}", 
                    id, relationDTO.getShopId(), relationDTO.getOwnerId());
            
            // 参数校验
            if (id == null || id <= 0) {
                return Result.fail("关联ID必须大于0");
            }
            
            // 业务参数校验
            validateShopOwnerRelationDTO(relationDTO);
            
            // 调用Service更新
            boolean success = shopOwnerRelationService.updateShopOwnerRelation(id, relationDTO);
            if (!success) {
                return Result.fail("关联关系不存在或更新失败");
            }
            
            log.info("更新店铺业主关联成功，ID：{}，店铺ID：{}，业主ID：{}", 
                    id, relationDTO.getShopId(), relationDTO.getOwnerId());
            return Result.success("更新成功", true);
        } catch (Exception e) {
            log.error("更新店铺业主关联失败，ID：{}，店铺ID：{}，业主ID：{}", 
                    id, relationDTO != null ? relationDTO.getShopId() : "未知", 
                    relationDTO != null ? relationDTO.getOwnerId() : "未知", e);
            return Result.fail("更新失败：" + e.getMessage());
        }
    }
    
    /**
     * 删除店铺业主关联
     */
    @ApiLog(
        logTitle = "删除店铺业主关联",
        logType = 2,
        moduleName = "店铺业主关联管理",
        operationType = ApiLogOperationType.DELETE
    )
    @DeleteMapping("/{id}")
    @Operation(summary = "删除店铺业主关联", description = "删除店铺业主关联关系")
    public Result<Boolean> deleteShopOwnerRelation(
            @Parameter(description = "关联ID", example = "1") @PathVariable Long id) {
        try {
            log.info("删除店铺业主关联，ID：{}", id);
            
            // 参数校验
            if (id == null || id <= 0) {
                return Result.fail("关联ID必须大于0");
            }
            
            // 调用Service删除
            boolean success = shopOwnerRelationService.deleteShopOwnerRelation(id);
            if (!success) {
                return Result.fail("关联关系不存在或删除失败");
            }
            
            log.info("删除店铺业主关联成功，ID：{}", id);
            return Result.success("删除成功", true);
        } catch (Exception e) {
            log.error("删除店铺业主关联失败，ID：{}", id, e);
            return Result.fail("删除失败：" + e.getMessage());
        }
    }
    
    /**
     * 根据店铺ID查询业主列表
     */
    @GetMapping("/shop/{shopId}/owners")
    @Operation(summary = "根据店铺ID查询业主列表", description = "根据店铺ID查询关联的业主列表")
    public Result<List<ShopOwnerRelationVO>> getOwnersByShopId(
            @Parameter(description = "店铺ID", example = "1") @PathVariable Long shopId) {
        try {
            log.info("根据店铺ID查询业主列表，店铺ID：{}", shopId);
            
            // 参数校验
            if (shopId == null || shopId <= 0) {
                return Result.fail("店铺ID必须大于0");
            }
            
            // 调用Service查询
            List<ShopOwnerRelationVO> ownerList = shopOwnerRelationService.getOwnersByShopId(shopId);
            
            log.info("根据店铺ID查询业主列表成功，店铺ID：{}，业主数量：{}", shopId, ownerList.size());
            return Result.success("查询成功", ownerList);
        } catch (Exception e) {
            log.error("根据店铺ID查询业主列表失败，店铺ID：{}", shopId, e);
            return Result.fail("查询失败：" + e.getMessage());
        }
    }
    
    /**
     * 根据业主ID查询关联店铺列表
     * 
     * 数据权限控制：
     * - 超级管理员：可以查看所有店铺数据
     * - 普通用户：只能查看用户关联社区内的店铺数据
     */
    @GetMapping("/owner/{ownerId}/shops")
    @Operation(summary = "根据业主ID查询关联店铺列表", description = "根据业主ID查询关联的店铺列表，支持数据权限控制")
    public Result<List<ShopOwnerRelationVO>> getShopsByOwnerId(
            @Parameter(description = "业主ID", example = "1") @PathVariable Long ownerId) {
        try {
            log.info("根据业主ID查询关联店铺列表，业主ID：{}", ownerId);
            
            // 参数校验
            if (ownerId == null || ownerId <= 0) {
                return Result.fail("业主ID必须大于0");
            }
            
            // 调用Service查询（包含数据权限控制）
            List<ShopOwnerRelationVO> shopList = shopOwnerRelationService.getShopsByOwnerId(ownerId);
            
            log.info("根据业主ID查询关联店铺列表成功，业主ID：{}，店铺数量：{}", ownerId, shopList.size());
            return Result.success("查询成功", shopList);
        } catch (Exception e) {
            log.error("根据业主ID查询关联店铺列表失败，业主ID：{}", ownerId, e);
            return Result.fail("查询失败：" + e.getMessage());
        }
    }
    
    /**
     * 批量设置店铺业主关联
     */
    @ApiLog(
        logTitle = "批量设置店铺业主关联",
        logType = 2,
        moduleName = "店铺业主关联管理",
        operationType = ApiLogOperationType.ADD
    )
    @PostMapping("/batch")
    @Operation(summary = "批量设置店铺业主关联", description = "批量设置店铺业主关联关系")
    public Result<Boolean> batchSetShopOwnerRelations(@RequestBody List<ShopOwnerRelationDTO> relationList) {
        try {
            log.info("批量设置店铺业主关联，关联数量：{}", relationList.size());
            
            // 参数校验
            if (relationList == null || relationList.isEmpty()) {
                return Result.fail("关联列表不能为空");
            }
            
            // 业务参数校验
            for (ShopOwnerRelationDTO relationDTO : relationList) {
                validateShopOwnerRelationDTO(relationDTO);
            }
            
            // 调用Service批量设置
            boolean success = shopOwnerRelationService.batchSetShopOwnerRelations(relationList);
            if (!success) {
                return Result.fail("批量设置失败");
            }
            
            log.info("批量设置店铺业主关联成功，关联数量：{}", relationList.size());
            return Result.success("批量设置成功", true);
        } catch (Exception e) {
            log.error("批量设置店铺业主关联失败，关联数量：{}", relationList.size(), e);
            return Result.fail("批量设置失败：" + e.getMessage());
        }
    }
    
    /**
     * 获取主要联系人
     */
    @GetMapping("/shop/{shopId}/primary-contact")
    @Operation(summary = "获取店铺主要联系人", description = "获取店铺的主要联系人信息")
    public Result<ShopOwnerRelationVO> getPrimaryContactByShopId(
            @Parameter(description = "店铺ID", example = "1") @PathVariable Long shopId) {
        try {
            log.info("获取店铺主要联系人，店铺ID：{}", shopId);
            
            // 参数校验
            if (shopId == null || shopId <= 0) {
                return Result.fail("店铺ID必须大于0");
            }
            
            // 调用Service查询
            ShopOwnerRelationVO primaryContact = shopOwnerRelationService.getPrimaryContactByShopId(shopId);
            if (primaryContact == null) {
                return Result.fail("该店铺暂无主要联系人");
            }
            
            log.info("获取店铺主要联系人成功，店铺ID：{}，主要联系人：{}", shopId, primaryContact.getOwnerName());
            return Result.success("查询成功", primaryContact);
        } catch (Exception e) {
            log.error("获取店铺主要联系人失败，店铺ID：{}", shopId, e);
            return Result.fail("查询失败：" + e.getMessage());
        }
    }
    
    /**
     * 店铺业主关联DTO业务规则验证
     */
    private void validateShopOwnerRelationDTO(ShopOwnerRelationDTO relationDTO) {
        // 店铺ID校验
        if (relationDTO.getShopId() == null || relationDTO.getShopId() <= 0) {
            throw new IllegalArgumentException("店铺ID必须大于0");
        }
        
        // 业主ID校验
        if (relationDTO.getOwnerId() == null || relationDTO.getOwnerId() <= 0) {
            throw new IllegalArgumentException("业主ID必须大于0");
        }
        
        // 关系类型校验
        if (relationDTO.getRelationType() == null) {
            throw new IllegalArgumentException("关系类型不能为空");
        }
        if (relationDTO.getRelationType() < 1 || relationDTO.getRelationType() > 3) {
            throw new IllegalArgumentException("关系类型必须是1（业主）、2（租户）或3（联合业主）");
        }
        
        // 所有权比例校验
        if (relationDTO.getOwnershipRatio() != null) {
            if (relationDTO.getOwnershipRatio().compareTo(BigDecimal.ZERO) < 0 || 
                relationDTO.getOwnershipRatio().compareTo(new BigDecimal("100")) > 0) {
                throw new IllegalArgumentException("所有权比例必须在0-100之间");
            }
        }
        
        // 租金价格校验
        if (relationDTO.getRentPrice() != null && relationDTO.getRentPrice().compareTo(BigDecimal.ZERO) < 0) {
            throw new IllegalArgumentException("租金价格不能为负数");
        }
        
        // 押金金额校验
        if (relationDTO.getDepositAmount() != null && relationDTO.getDepositAmount().compareTo(BigDecimal.ZERO) < 0) {
            throw new IllegalArgumentException("押金金额不能为负数");
        }
        
        // 主要联系人校验
        if (relationDTO.getIsPrimary() != null && (relationDTO.getIsPrimary() < 0 || relationDTO.getIsPrimary() > 1)) {
            throw new IllegalArgumentException("主要联系人标识必须是0（否）或1（是）");
        }
        
        // 状态校验
        if (relationDTO.getStatus() != null && (relationDTO.getStatus() < 0 || relationDTO.getStatus() > 1)) {
            throw new IllegalArgumentException("状态必须是0（禁用）或1（启用）");
        }
    }
}